import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import quick.dbtable.*;

/**
 * A JPanel for viewing goals. Navigation to this Viewer is done by Explorer.
 *
 * @author Jacel Evasco
 * @author Roselle Nympha Lim
 * @author Kriss Ford Ulat
 * @version 1.0
 */
public class GoalsViewer extends JPanel {

    private DBTable data = new DBTable();
    private JTextField searchBar = new JTextField("search...");
    private JButton add = new JButton(new ImageIcon(
        "images\\icons\\addNormal.png"));
    private JButton edit = new JButton(new ImageIcon(
        "images\\icons\\editNormal.png"));
    private JButton delete = new JButton(new ImageIcon(
        "images\\icons\\deleteNormal.png"));
    private JPanel head = new JPanel();
    private JPanel body = new JPanel();
    private JLabel shadow = new JLabel(new ImageIcon(
        "images\\backgrounds\\RGViewerShadow.png"));
    private GoalEditor goalEditor = new GoalEditor();

    public GoalsViewer() {
        assemble();
        configure();
        design();
        setTriggers();
    }// end of GoalsViewer()

    private void assemble() {
        // head
        head.setLayout(new BoxLayout(head, BoxLayout.X_AXIS));
        head.add(Box.createRigidArea(new Dimension(23, 0)));
        head.add(searchBar);
        head.add(Box.createRigidArea(new Dimension(483, 0)));
        head.add(add);
        head.add(Box.createRigidArea(new Dimension(15, 0)));
        head.add(edit);
        head.add(Box.createRigidArea(new Dimension(15, 0)));
        head.add(delete);
        // body
        body.setLayout(new BoxLayout(body, BoxLayout.X_AXIS));
        body.add(Box.createRigidArea(new Dimension(23, 0)));
        body.add(data);
        // shadow
        shadow.setLayout(new BoxLayout(shadow, BoxLayout.Y_AXIS));
        shadow.add(Box.createRigidArea(new Dimension(0, 25)));
        shadow.add(head);
        shadow.add(Box.createRigidArea(new Dimension(0, 15)));
        shadow.add(body);
        // content
        this.setLayout(new BorderLayout());
        this.add(shadow);
    }// end of assemble()

    private void configure() {
        data.setEditable(false);
        try {
            data.connectDatabase(
                "com.mysql.jdbc.Driver",
                "jdbc:mysql://localhost:3306/"
                    + "requirementstrackerschema?allowMultiQueries=true",
                "root", "");
            data.setSelectSql("SELECT goal.goalID AS id, "
                + "goal.name AS goal, "
                + "requirement.name AS requirement, "
                + "DATE_FORMAT(goal.due, '%d %M %Y') AS due, "
                + "goal.status, "
                + "goal.priority, "
                + "goal.notes "
                + "FROM goal "
                + "JOIN requirement "
                + "ON goal.requirementID = requirement.requirementID "
                + "JOIN student "
                + "ON requirement.studentID = student.studentID "
                + "WHERE student.isLoggedIn = 1");
            data.refresh();
        } catch (Exception noise) {
            noise.printStackTrace();
        }

        isDataEmpty();
        (data.getColumnAsCreated(0)).setVisible(false);
        (data.getColumnAsCreated(1)).setPreferredWidth(160);
        (data.getColumnAsCreated(2)).setPreferredWidth(185);
        (data.getColumnAsCreated(3)).setPreferredWidth(180);
        (data.getColumnAsCreated(4)).setPreferredWidth(70);
        (data.getColumnAsCreated(5)).setPreferredWidth(72);
        (data.getColumnAsCreated(6)).setPreferredWidth(217);
    }// end of configure()

    private void design() {
        // sizes
        searchBar.setPreferredSize(new Dimension(294, 32));
        searchBar.setMinimumSize(new Dimension(294, 32));
        searchBar.setMaximumSize(new Dimension(294, 32));
        add.setPreferredSize(new Dimension(32, 32));
        add.setMinimumSize(new Dimension(32, 32));
        add.setMaximumSize(new Dimension(32, 32));
        edit.setPreferredSize(new Dimension(32, 32));
        edit.setMinimumSize(new Dimension(32, 32));
        edit.setMaximumSize(new Dimension(32, 32));
        delete.setPreferredSize(new Dimension(32, 32));
        delete.setMinimumSize(new Dimension(32, 32));
        delete.setMaximumSize(new Dimension(32, 32));
        data.setPreferredSize(new Dimension(904, 475));
        data.setMinimumSize(new Dimension(904, 475));
        data.setMaximumSize(new Dimension(904, 475));
        head.setPreferredSize(new Dimension(954, 32));
        head.setMinimumSize(new Dimension(954, 32));
        head.setMaximumSize(new Dimension(954, 32));
        body.setPreferredSize(new Dimension(954, 475));
        body.setMinimumSize(new Dimension(954, 475));
        body.setMaximumSize(new Dimension(954, 475));
        this.setPreferredSize(new Dimension(954, 600));
        this.setMinimumSize(new Dimension(954, 600));
        this.setMaximumSize(new Dimension(954, 600));
        // colors
        Color gray = new Color(238, 238, 238);
        Color darkGray = new Color(180, 180, 180);
        // font styles
        searchBar.setFont(new Font("Segoe UI", Font.PLAIN, 20));
        // font colors
        searchBar.setForeground(darkGray);
        // borders
        searchBar.setBorder(BorderFactory.createLineBorder(
            Color.BLACK, 1));
        data.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        // backgrounds
        this.setOpaque(false);
        head.setOpaque(false);
        body.setOpaque(false);
        // button styles
        add.setOpaque(false);
        add.setContentAreaFilled(false);
        add.setBorderPainted(false);
        edit.setOpaque(false);
        edit.setContentAreaFilled(false);
        edit.setBorderPainted(false);
        delete.setOpaque(false);
        delete.setContentAreaFilled(false);
        delete.setBorderPainted(false);
        // table skin
        data.setSkin(new ViewerTableSkin());
    }// end of design()

    private void setTriggers() {

        ActionListener actionTrigger = new ActionListener() {
            public void actionPerformed(ActionEvent anActionEvent) {
                if (anActionEvent.getSource() == add) {
                    try {
                        goalEditor.setEditMode(false);
                        goalEditor.fetchRequirements();
                        goalEditor.clear();
                    } catch (Exception noise) {
                        noise.printStackTrace();
                    }
                    goalEditor.setVisible(true);
                } else if (anActionEvent.getSource() == edit) {
                    try {
                        goalEditor.setEditMode(true);
                        goalEditor.fetchRequirements();

                        goalEditor
                            .load(Long.toString((Long) data.getValueAt(
                                data.getSelectedRow(),
                                data.getCurrentIndexForOriginalColumn(0))));
                    } catch (Exception noise) {
                        noise.printStackTrace();
                    }
                    goalEditor.setVisible(true);
                } else if (anActionEvent.getSource() == delete) {
                    int selection = JOptionPane
                        .showOptionDialog(
                            null,
                            "You are about to delete a goal. Are you sure?",
                            "Confirm operation",
                            JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE, null, null,
                            null);
                    switch (selection) {
                    case 0:
                        try {
                            DatabaseUtility
                                .executeQuery("DELETE FROM goal WHERE goal.goalID = "
                                    + Long.toString((Long) data.getValueAt(
                                        data.getSelectedRow(),
                                        data.getCurrentIndexForOriginalColumn(0))));
                            data.refresh();
                            Explorer.getInstance().getGoalsViewer()
                                .getData().refresh();
                            Explorer.getInstance()
                                .getRequirementsViewer().getData()
                                .refresh();
                            Explorer.getInstance().getGoalsViewer()
                                .isDataEmpty();
                            Explorer.getInstance()
                                .getRequirementsViewer()
                                .isDataEmpty();
                        } catch (Exception noise) {
                        }
                    }
                } else if (anActionEvent.getSource() == searchBar) {
                    searchBar.selectAll();
                }
            }
        };// end of actionTrigger

        MouseListener mouseTrigger = new MouseListener() {
            public void mouseClicked(MouseEvent me) {
            } // end of mouseClicked()

            public void mouseEntered(MouseEvent me) {
                if (me.getSource() == add) {
                    add.setIcon(new ImageIcon(
                        "images\\icons\\addEntered.png"));
                }
                if (me.getSource() == edit) {
                    edit.setIcon(new ImageIcon(
                        "images\\icons\\editEntered.png"));
                }
                if (me.getSource() == delete) {
                    delete.setIcon(new ImageIcon(
                        "images\\icons\\deleteEntered.png"));
                }
            } // end of mouseEntered()

            public void mouseExited(MouseEvent me) {
                if (me.getSource() == add) {
                    add.setIcon(new ImageIcon(
                        "images\\icons\\addNormal.png"));
                }
                if (me.getSource() == edit) {
                    edit.setIcon(new ImageIcon(
                        "images\\icons\\editNormal.png"));
                }
                if (me.getSource() == delete) {
                    delete.setIcon(new ImageIcon(
                        "images\\icons\\deleteNormal.png"));
                }
            } // end of mouseExited()

            public void mousePressed(MouseEvent me) {
                if (me.getSource() == add) {
                    add.setIcon(new ImageIcon(
                        "images\\icons\\addPressed.png"));
                }
                if (me.getSource() == edit) {
                    edit.setIcon(new ImageIcon(
                        "images\\icons\\editPressed.png"));
                }
                if (me.getSource() == delete) {
                    delete.setIcon(new ImageIcon(
                        "images\\icons\\deletePressed.png"));
                }
            } // end of mousePressed()

            public void mouseReleased(MouseEvent me) {
                if (me.getSource() == add) {
                    add.setIcon(new ImageIcon(
                        "images\\icons\\addNormal.png"));
                }
                if (me.getSource() == edit) {
                    edit.setIcon(new ImageIcon(
                        "images\\icons\\editNormal.png"));
                }
                if (me.getSource() == delete) {
                    delete.setIcon(new ImageIcon(
                        "images\\icons\\deleteNormal.png"));
                }
            }
        };// end of mouseTrigger

        DocumentListener documentTrigger = new DocumentListener() {
            public void changedUpdate(DocumentEvent aDocumentEvent) {
            }

            public void insertUpdate(DocumentEvent aDocumentEvent) {
                try {
                    data.setSelectSql("SELECT goal.goalID AS ID, "
                        + "goal.name AS goal, "
                        + "requirement.name AS requirement, "
                        + "DATE_FORMAT(goal.due, '%d %M %Y') AS due, "
                        + "goal.status, "
                        + "goal.priority, "
                        + "goal.notes "
                        + "FROM goal "
                        + "JOIN requirement "
                        + "ON goal.requirementID = requirement.requirementID "
                        + "JOIN student "
                        + "ON requirement.studentID = student.studentID "
                        + "WHERE student.isLoggedIn = 1 "
                        + "AND CONCAT(goal.name, ' ', requirement.name, ' ', "
                        + "DATE_FORMAT(goal.due, '%d %M %Y'), ' ', "
                        + "goal.status, ' ', goal.priority, ' ', goal.notes) "
                        + "LIKE (\"%" + searchBar.getText() + "%\")");

                    data.refresh();

                    (data.getColumnAsCreated(0)).setVisible(false);
                    (data.getColumnAsCreated(1))
                        .setPreferredWidth(160);
                    (data.getColumnAsCreated(2))
                        .setPreferredWidth(185);
                    (data.getColumnAsCreated(3))
                        .setPreferredWidth(180);
                    (data.getColumnAsCreated(4))
                        .setPreferredWidth(70);
                    (data.getColumnAsCreated(5))
                        .setPreferredWidth(72);
                    (data.getColumnAsCreated(6))
                        .setPreferredWidth(217);

                } catch (Exception noise) {
                    noise.printStackTrace();
                }
            }// end of insertUpdate()

            public void removeUpdate(DocumentEvent aDocumentEvent) {
                try {
                    data.setSelectSql("SELECT goal.goalID AS ID, "
                        + "goal.name AS goal, "
                        + "requirement.name AS requirement, "
                        + "DATE_FORMAT(goal.due, '%d %M %Y') AS due, "
                        + "goal.status, "
                        + "goal.priority, "
                        + "goal.notes "
                        + "FROM goal "
                        + "JOIN requirement "
                        + "ON goal.requirementID = requirement.requirementID "
                        + "JOIN student "
                        + "ON requirement.studentID = student.studentID "
                        + "WHERE student.isLoggedIn = 1 "
                        + "AND CONCAT(goal.name, ' ', requirement.name, ' ', "
                        + "DATE_FORMAT(goal.due, '%d %M %Y'), ' ', "
                        + "goal.status, ' ', goal.priority, ' ', goal.notes) "
                        + "LIKE (\"%" + searchBar.getText() + "%\")");
                    data.refresh();
                    (data.getColumnAsCreated(0)).setVisible(false);
                    (data.getColumnAsCreated(1))
                        .setPreferredWidth(160);
                    (data.getColumnAsCreated(2))
                        .setPreferredWidth(185);
                    (data.getColumnAsCreated(3))
                        .setPreferredWidth(180);
                    (data.getColumnAsCreated(4))
                        .setPreferredWidth(70);
                    (data.getColumnAsCreated(5))
                        .setPreferredWidth(72);
                    (data.getColumnAsCreated(6))
                        .setPreferredWidth(217);
                } catch (Exception noise) {
                    noise.printStackTrace();
                }
            }// end of removeUpdate()
        };// end of documentTrigger

        DBTableEventListener tableTrigger = new DBTableEventListener() {
            public boolean beforeRowSelectionChange(
                int fromRow, int toRow, int fromColumn, int toColumn) {
                data.setRowSelectionInterval(toRow, toRow);
                return false;
            }// end of beforeRowSelectionChange

            public boolean beforeColumnSelectionChange(
                int fromColumn, int toColumn, int fromRow, int toRow) {
                return true;
            }// end of beforeColumnSelectionChange

            public void afterRowSelectionChange(int fromRow, int toRow) {
            }// end of afterRowSelectionChange

            public void afterColumnSelectionChange(
                int fromColumn, int toColumn) {
            }// end of afterColumnSelectionChange

            public boolean onSortColumn(int column, boolean ascending) {
                return true;
            }// end of onSortColumn
        };// end of tableTrigger

        add.addMouseListener(mouseTrigger);
        add.addActionListener(actionTrigger);
        edit.addMouseListener(mouseTrigger);
        edit.addActionListener(actionTrigger);
        delete.addMouseListener(mouseTrigger);
        delete.addActionListener(actionTrigger);
        searchBar.addMouseListener(mouseTrigger);
        searchBar.getDocument().addDocumentListener(documentTrigger);
        searchBar.addActionListener(actionTrigger);
        data.addDBTableEventListener(tableTrigger);
    }// end of setTriggers()

    public boolean isDataEmpty() {
        String[][] temp = {};
        try {
            temp = DatabaseUtility.getResults("SELECT goal.goalID "
                + "FROM goal " + "NATURAL JOIN student "
                + "WHERE student.isLoggedIn = 1 ");
        } catch (Exception warning) {
            warning.printStackTrace();
        }
        if (temp.length == 0) {
            edit.setEnabled(false);
            delete.setEnabled(false);
            return true;
        } else {
            edit.setEnabled(true);
            delete.setEnabled(true);
            return false;
        }
    }// end of isDataEmpty()

    public DBTable getData() {
        return data;
    }// end of getData()

    public String getSelectedID() {
        return Long.toString((Long) (data.getValueAt(
            data.getSelectedRow(),
            data.getCurrentIndexForOriginalColumn(0))));
    }// end of getSelectedID
}// end of GoalsViewer